home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / util / cdity / ModeProSrc.lha / Daemon / MPCloseScrPatch.c < prev    next >
C/C++ Source or Header  |  1998-10-21  |  12KB  |  247 lines

  1. #define DEBUG
  2. #include <debug.h>
  3.  
  4. #include "MP.h"
  5. //#include "/modepro.h"
  6. #include <graphics/videocontrol.h>
  7. #include <graphics/displayinfo.h>
  8. #include "patchdata.h"
  9.  
  10. #include <extras/macros/exec.h>
  11.  
  12. // Window
  13.  
  14. #ifdef DEBUG
  15. #define ADD_DEBUG_CODE
  16. #endif
  17.  
  18. extern LONG   InPatch;
  19. extern BYTE   PublicSignal;
  20. extern struct MPSem *MPSem;
  21. extern struct Process  *MPTask;
  22. extern LONG ASM (*OldCloseScreen)   (REG __a0 struct Screen *,REG __a6 struct IntuitionBase *);
  23. extern LONG ASM (*OldCloseWorkBench)(REG __a6 struct IntuitionBase *lib);
  24.  
  25.  
  26. /* 4.53 moved closing ccde to NewCloseScreen() */
  27. /* called by ModePro */
  28.  
  29. /* transplanted from mpmain.c *///                                                                     (4.55.6)
  30. void ClosePubScreens(void)  //                                                                         (4.55.6)
  31. {
  32.   struct OpenNode *on,*on2;
  33. //  struct List *plist;
  34. //  struct PubScreenNode *psn;
  35.  
  36.  
  37.   ObtainSemaphore(&MPSem->OpenListSem);
  38.  
  39. /*  
  40.   // 4.53 @10 Scan pubscreen list and check for screens that need to be closed  
  41.   plist=LockPubScreenList();
  42.  
  43.   PROCESS_LIST(plist,psn)
  44.   {
  45.     if(on=FindOpenNode(psn->psn_Screen))
  46.     {
  47.       if(psn->psn_VisitorCount<=1) // birdie kludge
  48.       {
  49.         on->Flags|=ON_CLOSEME;
  50.       }
  51.     }
  52.   }
  53.   UnlockPubScreenList();
  54.   */
  55.   
  56.   on=(struct OpenNode *)MPSem->OpenList.lh_Head;
  57.   
  58.   // 4.53 rewritten
  59.   while(on->on_Node.ln_Succ)
  60.   {
  61.     on2=(struct OpenNode *)on->on_Node.ln_Succ;
  62.     if( (on->Flags & ON_PUBLIC)   && 
  63. //        (on->Flags & ON_CLOSEME)  && 
  64.        !(on->Flags & ON_OPEN)     && 
  65.         (0==on->Screen->FirstWindow))
  66.     {
  67.       CloseScreen(on->Screen);
  68.     }
  69.     on=on2;
  70.   }
  71.  
  72.   ReleaseSemaphore(&MPSem->OpenListSem);
  73. }
  74.  
  75. /* Birdie Kludge:
  76.     Every time a program UnlockPubScreen()s a screen, MPPatch will signal MP
  77.     itself and call ClosePubScreens(), every public screen in the OpenList 
  78.     with no windows on it will get a CloseScreen() call,  if it suceeds then 
  79.     great, if not then someone else has a lock on it.
  80. */
  81.  
  82. LONG __saveds ASM NewCloseScreen(REG __a0 struct Screen *S,//                                          (4.56.5)
  83.                                  REG __a6 struct IntuitionBase *IBase)//                               (4.56.5)
  84. {
  85.   struct OpenNode *on;
  86.   BOOL rv;
  87.   LONG myrv;
  88.   char tnamebuffer[52];
  89.   char *tname;
  90.   
  91.   InPatch++;
  92.  
  93.   tname=SetupTaskName(tnamebuffer,", CS",50);
  94.  
  95. DEBUG_CODE(DKP("CloseScreen(%8lx)\n",S););
  96.  
  97.   ObtainSemaphore(&MPSem->OpenListSem);
  98.   
  99.   // 4.53 @3
  100.   if(on=FindOpenNode(S))
  101.   {
  102. DEBUG_CODE(DKP("  ModePro has an OpenNode for this screen\n"););
  103.     // 4.53 @12
  104.     if(on->Flags & ON_PUBLIC)                           // If this OpenNode belongs to a ModePro public screen then...
  105.     {
  106. DEBUG_CODE(DKP("  ModePro made screen public\n"););
  107.       if(on->Flags & ON_OPEN)
  108.       { // give control of this screen to MP
  109.         on->Flags&=(~ON_OPEN);                          // This screen is nolonger owned by the program that opened it
  110.         S->DefaultTitle=0;
  111.         S->Title=0;//on->ScreenTitle;                   // Reset title since app owns the string.
  112.         ShowTitle(S,TRUE);                              // Refresh Titlebar
  113.         
  114.         on->Flags|=(ON_CLOSEME);                        // 4.53 @4 - Set flag so MP knows which OpenNode caused signal
  115.         
  116.         Signal((struct Task *)MPTask,1<<PublicSignal);  // Signal ModePro so it knows that it should attempt to close this screen
  117.         rv=1;                                        // Fake return value, so that apps that DO check this value will think 
  118.                                                         // that the screen really did close
  119.  
  120. DEBUG_CODE(DKP("  CloseScreen() fakes close\n"););
  121.  
  122.       }
  123.       else                                              // since not ON_OPEN, ModePro itself is trying to close 
  124.       {
  125.         BOOL closeit=0;
  126.         BOOL ispublic=0;
  127.         
  128.         struct PubScreenNode *psn;
  129.         struct List *plist;
  130.         
  131. DEBUG_CODE(DKP("  This should only happen on ModePro's task\n"););//                                         (4.55.7)
  132.         
  133.         rv=0;                                           // 4.55 @3 - rv was not initialized to 0 till 4.55
  134.         
  135.         /* The big birdie kludge //                                                                    (4.55.7)
  136.             1. Check to see if the screen is private//                                                 (4.55.7)
  137.             2. Find out if the screen is private (used later)//                                        (4.55.7)
  138.             3. Attempt to make the screen private.  This should remove any visitors from the screennotify library. (Birdie)//  (4.55.7)
  139.             4. Check to see if any visitors are on the screen //                                       (4.55.7)
  140.                If none then try to close it//                                                          (4.55.7)
  141.             5. If it didn't close for some odd reason, then add the backdrop and make the screen public again//  (4.55.7)
  142.         *///                                                                                           (4.55.7)
  143.         plist=LockPubScreenList();                      //                                             (4.55.7)
  144.         PROCESS_LIST(plist,psn)//                                                                      (4.55.7)
  145.         {//                                                                                            (4.55.7)
  146.           if(S==psn->psn_Screen)//                                                                     (4.55.7)
  147.           {//                                                                                          (4.55.7)
  148.             ispublic=!(psn->psn_Flags & PSNF_PRIVATE);//                                               (4.55.7)
  149.           }//                                                                                          (4.55.7)
  150.         }//                                                                                            (4.55.7)
  151.         UnlockPubScreenList();//                                                                       (4.55.7)
  152.         //                                                                                             (4.55.7)
  153.         PubScreenStatus(S,PSNF_PRIVATE); //                                                            (4.55.7)
  154.         //                                                                                             (4.55.7)
  155.         plist=LockPubScreenList();                      //                                             (4.55.7)
  156.         PROCESS_LIST(plist,psn)//                                                                      (4.55.7)
  157.         {//                                                                                            (4.55.7)
  158.           if(S==psn->psn_Screen)//                                                                     (4.55.7)
  159.           {//                                                                                          (4.55.7)
  160.             if(psn->psn_VisitorCount==0)//                                                             (4.55.7)
  161.             {//                                                                                        (4.55.7)
  162.               closeit=1;//                                                                             (4.55.7)
  163.             }//                                                                                        (4.55.7)
  164.           }//                                                                                          (4.55.7)
  165.         }//                                                                                            (4.55.7)
  166.         UnlockPubScreenList();//                                                                       (4.55.7)
  167.         //                                                                                             (4.55.7)
  168.         if(closeit)// Only close it if no visitors                                                     (4.55.7)
  169.         {//                                                                                            (4.55.7)
  170.           RemoveBackdrop(S);    // Remove any backdrop (handles no backdrops)                          (4.55.7)
  171.           PreCloseOpenNode(on); // Free data that needs to be freed BEFORE the screen closes (ie Pens) (4.55.7)
  172.           //                                                                                           (4.55.7)
  173.           if(rv=OldCloseScreen(S,IntuitionBase)) // Attempt to Close the screen         //             (4.55.7)
  174.           {//                                                                                          (4.55.7)
  175.             Remove((struct Node *)on);                  // 4.53 @12 - Remove Node from OpenList//      (4.55.7)
  176.             FreeOpenNode(on);                           // Free the OpenNode//                         (4.55.7)
  177. DEBUG_CODE(DKP("  CloseScreen() really closes screen!\n"););//                                         (4.55.7)
  178.           }//                                                                                          (4.55.7)
  179.         }//                                                                                            (4.55.7)
  180.         //                                                                                             (4.55.7)
  181.         if(ispublic && !rv)                     // if the screen was public and closescreen failed.//  (4.55.7)
  182.         {//                                                                                            (4.55.7)
  183.           PubScreenStatus(S,0);                // Then make the screen public again.//        (4.55.7)
  184.           AddBackdrop(S,on->DN);               // Re add the backdrop//                       (4.55.7)
  185.         }//                                                                                            (4.55.7)
  186.       }//                                                                                              (4.55.7)
  187.     }
  188.     else                                                // If this OpenNode belongs to a non-public promoted screen.
  189.     {
  190. DEBUG_CODE(DKP("  ModePro did NOT make screen public\n"););
  191.       
  192.       SendMPMsg(MP_SCREENCLOSING,0,on);                 // Let ModePro know that we're closing this screen.
  193.       PreCloseOpenNode(on);                             // Free data that needs to be freed BEFORE the screen closes (ie Pens)
  194.  
  195.       if(rv=OldCloseScreen(S,IBase))                    // Attempt to Close the screen
  196.       {
  197.         Remove((struct Node *)on);                      // 4.53 @12 - Remove Node from OpenList
  198.         FreeOpenNode(on);                               // Free the OpenNode
  199.       }
  200.     }
  201.   }
  202.   else // on==NULL
  203.   { // Non-promoted screen 
  204. DEBUG_CODE(DKP("  ModePro doesn't have an OpenNode for this screen\n"););
  205.     rv=OldCloseScreen(S,IBase);
  206.   }
  207.  
  208.   myrv=(rv?1:0);
  209.  
  210. DEBUG_CODE( DKP("  RV=%lx (1 second delay)\n",myrv);
  211.             Delay(50); );
  212.  
  213.   InPatch--;
  214.   
  215.   ReleaseSemaphore(&MPSem->OpenListSem);
  216.   
  217.   SetTaskName(tname);
  218.   
  219.   return(myrv);
  220. }
  221.  
  222.  
  223. LONG __saveds ASM NewCloseWorkBench(REG __a6 struct IntuitionBase *IBase)
  224. {   
  225.   LONG retval;
  226.   char tnamebuffer[52];
  227.   char *tname;
  228.   
  229.   tname=SetupTaskName(tnamebuffer,", CWB",50);
  230.   
  231. DEBUG_CODE(DKP("CloseWorkBench()\n"););
  232.  
  233.   //ObtainSemaphore(&MPSem->OpenListSem);
  234.   //SendMPMsg(MP_SCREENCLOSING,0,0,ON);
  235.   PreCloseWBOpenNode();
  236.   if(retval=OldCloseWorkBench(IBase))
  237.     FreeWBOpenNode();
  238.   
  239.   //ReleaseSemaphore(&MPSem->OpenListSem);
  240.  
  241. DEBUG_CODE(DKP("  RV=%d\n",retval););
  242.   
  243.   SetTaskName(tname);
  244.   
  245.   return(retval);
  246. }
  247.